/*
 * display.c
 *
 */
#include "display.h"
#include "flash.h"

/**
 * externs
 *
 */

/**
 * globals
 *
 */
// 按键
bool keyFunction, keyUp, keyDown, keyEnter;
bool keyFunctionPosedge, keyUpPosedge, keyDownPosedge, keyEnterPosedge;
// 计时
uint32_t tickCountIncrease, tickCountDecrease;
// 显示计时
uint32_t tickCountMain;
// 显示选择
uint16_t displaySelect;
//参数操作
int16_t function, functionNumber;
//显示值
int16_t value;
//设定值
int32_t valueSet;
// 闪烁位置
int8_t bitFlash = -1;

/**
 * display init
 *
 * @param
 * @return
 */
void displayInit(void) {
	// 显示buffer
	uint8_t displayBuffer[4];
	// 设定闪烁，-1为全不闪烁
	bitFlash = -1;
	if (tickCountIncrease < 1000) {
		//第1秒全显示
		displayBuffer[0] = 0x00;
		displayBuffer[1] = 0x00;
		displayBuffer[2] = 0x00;
		displayBuffer[3] = 0x00;
		led8s595SetDisplayBuffer(displayBuffer, 0);
		led8s595SetDisplayBuffer(displayBuffer, 1);
	} else if (tickCountIncrease < 4000) {
		//第2-4秒显示型号
		// rec
		displayBuffer[0] = getTruthLetter('Y');
		displayBuffer[1] = getTruthLetter('E');
		displayBuffer[2] = getTruthLetter('M');
		displayBuffer[3] = getTruthLetter('C');
		led8s595SetDisplayBuffer(displayBuffer, 0);
		// 1.00
		displayBuffer[0] = getTruthLetter('B');
		displayBuffer[1] = getTruthNumber(1);
		displayBuffer[2] = getTruthNumber(0);
		displayBuffer[3] = getTruthNumber(3);
		led8s595SetDisplayBuffer(displayBuffer, 1);

	} else {
		tickCountIncrease = 0;
		displaySelect = DISPLAY_MAIN;
	}
}

/**
 * display main
 *
 * @param
 * @return
 */
void displayMain(void) {
	// 设定闪烁，-1为全不闪烁
	bitFlash = -1;
	// 轮换显示
	uint16_t value0 = 0;
	if (discreteInput[0]) {
		value0 += 1;
	}
	if (discreteInput[1]) {
		value0 += 10;
	}
	led8s595SetInteger(holdingRegister[0], 1, 0);
	led8s595SetInteger(holdingRegister[1], 1, 1);
	//长按FUC键
	if (keyFunction) {
		if (tickCountIncrease > 3000) {

			keyFunctionPosedge = true;
			tickCountIncrease = 0;
			function = REGISTER_HR;
			functionNumber = -1;
			displaySelect = DISPLAY_FUNCTION;
		}
	} else {
		tickCountIncrease = 0;
	}
}

/**
 * get function truth
 *
 * @param
 * @return
 */
static void getFunctionTruth(uint8_t *buffer) {
	// 清空
	memset(buffer, 0xFF, 4);
	// 寄存器
	if (function == REGISTER_C) {
		buffer[0] = getTruthLetter('C');
	} else if (function == REGISTER_DI) {
		buffer[0] = getTruthLetter('D');
		buffer[1] = getTruthLetter('I');
	} else if (function == REGISTER_HR) {
		buffer[0] = getTruthLetter('H');
		buffer[1] = getTruthLetter('R');
	} else if (function == REGISTER_IR) {
		buffer[0] = getTruthLetter('I');
		buffer[1] = getTruthLetter('R');
	} else if (function == REGISTER_F) {
		buffer[0] = getTruthLetter('F');
	} else {
		buffer[0] = getTruthLetter('E');
		buffer[1] = getTruthLetter('R');
		buffer[2] = getTruthLetter('R');
		return;
	}
	// 寄存器地址
	if (functionNumber >= 0 && functionNumber <= 99) {
		// buffer[1] = getTruthNumber(functionNumber % 1000 / 100);
		buffer[2] = getTruthNumber(functionNumber % 100 / 10);
		buffer[3] = getTruthNumber(functionNumber % 10 / 1);
	}
}

/**
 * display function
 *
 * @param
 * @return
 */
void displayFunction(void) {
	// 显示buffer
	uint8_t displayBuffer[4];
	// 设定闪烁，-1为全不闪烁
	bitFlash = -1;
	//功能键
	if (isPosedge(keyFunction, &keyFunctionPosedge)) {
		displaySelect = DISPLAY_MAIN;
	}
	//上键
	if (isPosedge(keyUp, &keyUpPosedge)) {

		function++;
	}
	//下键
	if (isPosedge(keyDown, &keyDownPosedge)) {

		function--;
	}
	//限定FUNCTION
	if (function >= REGISTER_END) {

		function = 1;
	}
	if (function < 1) {

		function = REGISTER_END - 1;
	}
	//设定键
	if (isPosedge(keyEnter, &keyEnterPosedge)) {
		//切换画面
		functionNumber = 0;
		displaySelect = DISPLAY_PARAM;
		tickCountIncrease = 0;
	}
	//显示
	//上管显示功能码
	memset(displayBuffer, 0xFF, 4);
	getFunctionTruth(displayBuffer);
	led8s595SetDisplayBuffer(displayBuffer, 0);
	//下管不显示
	memset(displayBuffer, 0xFF, 4);
	led8s595SetDisplayBuffer(displayBuffer, 1);
}

/**
 * 寄存器地址限制
 *
 * @param
 * @return
 */
static bool registerNumberLimit(int16_t *_number, int16_t min, int16_t max) {
	if (*_number > max)
		*_number = min;
	if (*_number < min)
		*_number = max;
	if (*_number >= min && *_number <= max) {
		return true;
	}
	return false;
}

/**
 * display param limit
 *
 * @param
 * @return
 */
static bool functionParamLimit(void) {
	if (function == REGISTER_C) {
		return registerNumberLimit(&functionNumber, 0, 7);
	} else if (function == REGISTER_DI) {
		return registerNumberLimit(&functionNumber, 0, 7);
	} else if (function == REGISTER_HR) {
		return registerNumberLimit(&functionNumber, 0, 31);
	} else if (function == REGISTER_IR) {
		return registerNumberLimit(&functionNumber, 0, 31);
	} else if (function == REGISTER_F) {
		return registerNumberLimit(&functionNumber, 0, 63);
	} else {
		// 如果出错了，返回true，不然while中的break无法执行
		return true;
	}
}

/**
 * 读出设定值
 *
 * @param
 * @return
 */
static void getValueSet(void) {
	if (function == REGISTER_C) {
		valueSet = coil[functionNumber];
	} else if (function == REGISTER_DI) {
		valueSet = discreteInput[functionNumber];
	} else if (function == REGISTER_HR) {
		valueSet = holdingRegister[functionNumber];
	} else if (function == REGISTER_IR) {
		valueSet = inputRegister[functionNumber];
	} else if (function == REGISTER_F) {
		valueSet = (int32_t) file[functionNumber];
	}
}

/**
 * display param
 *
 * @param
 * @return
 */
void displayParam(void) {
	// 显示buffer
	uint8_t displayBuffer[4];
	// 设定闪烁，-1为全不闪烁
	bitFlash = -1;
	//在功能界面按功能键返回上一层
	if (isPosedge(keyFunction, &keyFunctionPosedge)) {
		functionNumber = -1;
		displaySelect = DISPLAY_FUNCTION;
	}
	//上键
	if (isPosedge(keyUp, &keyUpPosedge)) {
		//限定P
		while (true) {
			functionNumber++;
			if (functionParamLimit())
				break;
		}
	}
	//下键
	if (isPosedge(keyDown, &keyDownPosedge)) {
		//限定P
		while (true) {
			functionNumber--;
			if (functionParamLimit())
				break;
		}
	}
	//设定键
	if (isPosedge(keyEnter, &keyEnterPosedge)) {
		// 读出设定值
		getValueSet();
		// 切换画面
		displaySelect = DISPLAY_SET;
		bitFlash = 0;
		tickCountIncrease = 0;
	}
	//显示
	//上管显示寄存器和地址
	memset(displayBuffer, 0xFF, 4);
	getFunctionTruth(displayBuffer);
	led8s595SetDisplayBuffer(displayBuffer, 0);
	//下管不显示
	memset(displayBuffer, 0xFF, 4);
	led8s595SetDisplayBuffer(displayBuffer, 1);
}

/**
 * 设定设定值
 *
 * @param
 * @return
 */
static void saveValueSet(void) {
	switch (function) {
	case REGISTER_HR:
		holdingRegister[functionNumber] = valueSet;
		break;
	case REGISTER_F:
		modifyFlash(valueSet, functionNumber);
		break;
	default:
		break;
	}
}

/**
 * display set
 *
 * @param
 * @return
 */
void displaySet(void) {
	// 显示buffer
	uint8_t displayBuffer[4];
	//功能键
	if (isPosedge(keyFunction, &keyFunctionPosedge)) {
		displaySelect = DISPLAY_PARAM;
	}
	//上键
	if (isPosedge(keyUp, &keyUpPosedge)) {
		if (function == REGISTER_C) {
			bitFlash = -1;
		} else if (function == REGISTER_DI) {
			bitFlash = -1;
		} else if (function == REGISTER_HR) {
			if (bitFlash == 7) {
				valueSet = 0 - valueSet;
			} else {
				valueSet += (int16_t) pow(10, bitFlash);
			}
		} else if (function == REGISTER_IR) {
			bitFlash = -1;
		} else if (function == REGISTER_F) {
			if (bitFlash == 7) {
				valueSet = 0 - valueSet;
			} else {
				valueSet += (int16_t) pow(10, bitFlash);
			}
		}
	}
	// 下键
	if (isPosedge(keyDown, &keyDownPosedge)) {
		if (function == REGISTER_C) {
			bitFlash = -1;
		} else if (function == REGISTER_DI) {
			bitFlash = -1;
		} else if (function == REGISTER_HR) {
			if (bitFlash == 7) {
				valueSet = 0 - valueSet;
			} else {
				valueSet -= (int16_t) pow(10, bitFlash);
			}
		} else if (function == REGISTER_IR) {
			bitFlash = -1;
		} else if (function == REGISTER_F) {
			if (bitFlash == 7) {
				valueSet = 0 - valueSet;
			} else {
				valueSet -= (int16_t) pow(10, bitFlash);
			}
		}
	}
	// 设定键单击
	if (isPosedge(keyEnter, &keyEnterPosedge)) {
		if (function == REGISTER_HR || function == REGISTER_F) {
			bitFlash++;
			if (bitFlash > 7)
				bitFlash = 0;
		}
	}
	// 设定键长按
	if (keyEnter) {
		// 长按
		if (tickCountIncrease > 3000) {
			// 保存设定
			saveValueSet();
			// 切换画面
			tickCountIncrease = 0;
			displaySelect = DISPLAY_SAVE;
		}
	} else {
		// 清除长按计时
		tickCountIncrease = 0;
	}
	// 显示
	if (function == REGISTER_C) {
		// 上管显示功能码
		getFunctionTruth(displayBuffer);
		led8s595SetDisplayBuffer(displayBuffer, 0);
		// 下管显示值
		bitFlash = -1;
		led8s595SetInteger(coil[functionNumber], 0, 1);
	} else if (function == REGISTER_DI) {
		// 上管显示功能码
		getFunctionTruth(displayBuffer);
		led8s595SetDisplayBuffer(displayBuffer, 0);
		// 下管显示值
		bitFlash = -1;
		led8s595SetInteger(discreteInput[functionNumber], 0, 1);
	} else if (function == REGISTER_HR) {
		// 显示设定值
		led8s595SetLong(valueSet, 0);
	} else if (function == REGISTER_IR) {
		// 上管显示功能码
		getFunctionTruth(displayBuffer);
		led8s595SetDisplayBuffer(displayBuffer, 0);
		// 下管显示值
		bitFlash = -1;
		led8s595SetInteger(inputRegister[functionNumber], 0, 1);
	} else if (function == REGISTER_F) {
		// 显示设定值
		led8s595SetLong(valueSet, 0);
	}
}

/**
 * display save
 *
 * @param
 * @return
 */
void displaySave(void) {
// 显示buffer
	uint8_t displayBuffer[4];
// 设定闪烁，-1为全不闪烁
	bitFlash = -1;
//上管显示寄存器和地址
	memset(displayBuffer, 0xFF, 4);
	getFunctionTruth(displayBuffer);
	led8s595SetDisplayBuffer(displayBuffer, 0);
// 下管显示save
	memset(displayBuffer, 0xFF, 4);
	displayBuffer[0] = getTruthLetter('S');
	displayBuffer[1] = getTruthLetter('A');
	displayBuffer[2] = getTruthLetter('V');
	displayBuffer[3] = getTruthLetter('E');
	led8s595SetDisplayBuffer(displayBuffer, 1);
//
	if (tickCountIncrease > 3000) {
		displaySelect = DISPLAY_PARAM;
		tickCountIncrease = 0;
	}
}

/**
 * 自动返回主界面
 *
 * @param
 * @return
 */
static void autoReturn(uint16_t timeOut) {
//
	static uint32_t tickCountAutoReturn;
//如果不在温度显示界面，长时间检测不到按键操作，返回温度显示
	if (displaySelect != DISPLAY_MAIN) {
		tickCountAutoReturn++;
		//如果有按键操作，重新计时
		if (keyFunction || keyUp || keyDown || keyEnter) {
			tickCountAutoReturn = 0;
		}
		//如果超过60S，返回温度显示画面
		if (tickCountAutoReturn > timeOut * 1000) {
			displaySelect = DISPLAY_MAIN;
		}
	} else {
		tickCountAutoReturn = 0;
	}
}

/**
 * 显示setup
 *
 * @param
 * @return
 */
void displaySetup(void) {

	displaySelect = DISPLAY_INIT;
}

/**
 * 显示Loop
 *
 * @param
 * @return
 */
void displayLoop(void) {
// 显示
	if (displaySelect == DISPLAY_INIT) {

		displayInit();
	} else if (displaySelect == DISPLAY_MAIN) {

		displayMain();
	} else if (displaySelect == DISPLAY_FUNCTION) {

		displayFunction();
	} else if (displaySelect == DISPLAY_PARAM) {

		displayParam();
	} else if (displaySelect == DISPLAY_SET) {

		displaySet();
	} else if (displaySelect == DISPLAY_SAVE) {

		displaySave();
	} else {

		displaySelect = DISPLAY_INIT;
	}
}

/**
 * 显示任务（1ms调用）
 *
 * @param
 * @return
 */
void displayTask1ms(void) {
// 595显示任务
	led8s595SetFlash(bitFlash);
	led8s595Task1ms();
//按键消抖
	static uint32_t time1, time2, time3, time4;
	digitalFilter(&keyFunction, KEY_FNC, 20, &time1);
	digitalFilter(&keyUp, KEY_UP, 20, &time2);
	digitalFilter(&keyDown, KEY_DOWN, 20, &time3);
	digitalFilter(&keyEnter, KEY_ENT, 20, &time4);
//tick count
	if (tickCountIncrease < 999999999)
		tickCountIncrease++;
	if (tickCountDecrease > 0)
		tickCountDecrease--;
// 无操作60S返回主界面
	autoReturn(60);
// 主界面轮换显示
	tickCountMain++;
	if (tickCountMain >= 6000)
		tickCountMain = 0;
}
